/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3ds.
 *
 * e3ds is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3ds is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3ds. If not, see <https://www.gnu.org/licenses/>.
 */

package rtree

import (
	"sync"
	"sync/atomic"
)

var entityPool = sync.Pool{
	New: func() any {
		atomic.AddUint64(&_gInstId, 1)
		return &Entity{
			id: _gInstId,
		}
	},
}

func newEntity(box rect, ctx Context) *Entity {
	e := entityPool.Get().(*Entity)
	e.box = box
	e.ctx = ctx
	return e
}

func freeEntity(e *Entity) {
	e.box.clean()
	e.father = nil
	e.ctx = nil
	entityPool.Put(e)
}

type Entity struct {
	id     Tag
	box    rect
	father *node
	ctx    Context
}

func (ts *Entity) UniqueID() Tag {
	return ts.id
}

func (ts *Entity) Context() Context {
	return ts.ctx
}

func (ts *Entity) Points() (Point, Point) {
	return ts.box.min, ts.box.max
}

func (ts *Entity) rect() *rect {
	return &ts.box
}

func (ts *Entity) areaCalc() {}

func (ts *Entity) setFather(f *node) {
	ts.father = f
}

func (ts *Entity) isOverlap(r *rect, withAdj bool, cb func(*Entity) bool) bool {
	if ts.box.isOverlap(r, withAdj) {
		return cb(ts)
	}
	return true
}

func (ts *Entity) free() {
	freeEntity(ts)
}
